package com.huawei.lynnbit.tool.cocos.processor.leaf;

import com.huawei.lynnbit.tool.cocos.config.game.GameConfig;
import com.huawei.lynnbit.tool.cocos.config.game.task.CopySnippetTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.ReplaceFileTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.ReplaceStringTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.Task;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class ReplaceProcessor extends LeafProcessor {
    public ReplaceProcessor(Task task, GameConfig gameConfig) {
        this.task = task;
        this.gameConfig = gameConfig;
    }

    @Override
    public void doProcess() throws IOException {
        processReplaceFile();
        processReplaceString();
    }

    private void processReplaceFile() throws IOException {
        if (!Task.TYPE_REPLACE_FILE.equals(task.getType())) {
            return;
        }

        ReplaceFileTask taskInfo = (ReplaceFileTask) task;
        taskInfo.presetDestPath(gameConfig);
        File file = new File(taskInfo.getSrcPath());
        if (file.isFile()) {
            FileUtils.copyFile(new File(taskInfo.getSrcPath()), new File(taskInfo.getDestPath()));
        }

        if (file.isDirectory()) {
            FileUtils.deleteQuietly(new File(taskInfo.getDestPath()));
            FileUtils.copyDirectory(new File(taskInfo.getSrcPath()), new File(taskInfo.getDestPath()));
        }
    }

    private void processReplaceString() throws IOException {
        if (!Task.TYPE_REPLACE_STRING.equals(task.getType())) {
            return;
        }

        ReplaceStringTask taskInfo = (ReplaceStringTask) task;
        taskInfo.presetDestPath(gameConfig);
        if (isReadyReplaced(taskInfo)) {
            return;
        }

        String context = FileUtils.readFileToString(new File(taskInfo.getSrcPath()), StandardCharsets.UTF_8);
        Pattern pattern = Pattern.compile(taskInfo.getSrcPattern());
        Matcher matcher = pattern.matcher(context);
        if (matcher.find()) {
            String newContext = matcher.replaceFirst(taskInfo.getDestString().replaceAll("\\\\", "\\\\\\\\"));
            FileUtils.write(new File(taskInfo.getSrcPath()), newContext, StandardCharsets.UTF_8);
        } else {
            log.error("not match pattern: {}", taskInfo.getSrcPattern());
            throw new IllegalStateException("not match pattern");
        }
    }

    private boolean isReadyReplaced(ReplaceStringTask taskInfo) throws IOException {
        String context = FileUtils.readFileToString(new File(taskInfo.getSrcPath()), StandardCharsets.UTF_8).replaceAll("(\n|\r\n)", "");
        return context.contains(taskInfo.getDestString().replaceAll("(\n|\r\n)", ""));
    }
}
